`timescale 1ns/1ns

module coverage_cross;
    // 定义指令类型和操作数宽度
    typedef enum {ADD, SUB} opcode_e;
    typedef enum {WIDTH8, WIDTH16} width_e;
    
    opcode_e opcode;
    width_e operand_width;

    // 时钟
    logic clk = 0;
    always #5 clk = ~clk;

    // 覆盖组定义
    covergroup cg @(posedge clk);
        opcode_cp: coverpoint opcode {
            bins add_op = {ADD};
            bins sub_op = {SUB};
        }
        width_cp: coverpoint operand_width {
            bins width_8  = {WIDTH8};
            bins width_16 = {WIDTH16};
        }
        
        // 交叉覆盖率：指令类型 x 操作数宽度
        cross_opcode_width: cross opcode_cp, width_cp;
    endgroup
    
    // 实例化覆盖组
    cg cg_inst = new();
    
    initial begin
        // ADD指令使用8位操作数
        opcode = ADD; operand_width = WIDTH8; @(posedge clk);
        
        // SUB指令使用16位操作数
        opcode = SUB; operand_width = WIDTH16; @(posedge clk);
        
        // ADD指令使用16位操作数
        opcode = ADD; operand_width = WIDTH16; @(posedge clk);
        
        // 缺少SUB指令使用8位操作数的组合
        
        #10;
        // 显示覆盖率结果
        $display("cross coverage: %.2f%%", cg_inst.cross_opcode_width.get_coverage());
        $finish;
    end
endmodule
